/**
 ******************************************************************************
 * @file touch_state.c
 * @author GX (2524913364@qq.com)
 * @brief 	触摸屏状态机：能识别单击、拖动、滑屏。(在以前的状态机 2.0.0 的基础上重写)
 * 					该模块需要用到队列内容，因此还需要与配套的队列文件一起使用 "tcState_queue.h"
 * 					
 * 					>>用户使用的接口
 * 						InitTouch_pthread()	创建一个线程初始化触摸屏状态机
 * 						touch_mode()				获取和设置状态机功能 @ref TOUCH_MODE_CONFIG
 * 						get_attr_touch() 		从状态队列中获取一个状态	
 * 					
 * 					在判断滑屏的时候也提供了两种算法供用户使用，通过宏的定义选择 TC_EXACT_SLIDE
 * 
 * @note		用户在退出时需要使用线程取消函数 pthread_cancel() 取消本线程，这样本模块申请，
 * 					的一些资源才能顺利释放掉
 * @version 3.0.0 
 * @date 2022-08-18
 * 
 * 
 ******************************************************************************
 *----------------------------------------------------------------------------*
 *  Remark         : Description                                              *
 *----------------------------------------------------------------------------*
 *  Change History :                                                          *
 *  <Date>     | <Version> | <Author>       | <Description>                   *
 *----------------------------------------------------------------------------*
 *  2022-08-18 | 3.0.0     | GX             | Create file                     *
 *----------------------------------------------------------------------------*
 *                                                                            *
 ******************************************************************************
 */


/*----------------------------- start of file -------------------------------*/

#ifndef _TOUCH_STATE_H
#define _TOUCH_STATE_H

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <linux/input.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <pthread.h>
#include "tcState_queue.h"

/** @defgroup ACCURATELY_DETERMINE_SLIDING_SCREEN_DIRECTION
 *  @{
 */
/**
 * @brief 精确地判断滑屏，如果不定义该宏则使用粗糙的方式判断。
 *        如果使用该宏则利用计算斜率的方式判断滑屏的方向
 */
// #define TC_EXACT_SLIDE

#ifdef TC_EXACT_SLIDE
  #define  UPPER_BORDER_OF_HORIZONTAL_SLOPE   1.154700    // tan30
  #define  LOWER_BORDER_OF_HORIZONTAL_SLOPE   -1.154700   // tan(-30)
  #define  LEFT_BORDER_OF_VERTICAL_SLOPE      -2.747477   // tan(-70)
  #define  RIGHT_BORDER_OF_VERTICAL_SLOPE     2.747477    // tan70
#endif /* TC_EXACT_SLIDE */
/** 
 *  @}
 */

#define TOUCH_PATH  "/dev/input/event0"

/** @defgroup TOUCH_MODE_CONFIG
 *  @{
 */
/**
 * @brief 用一个 8 位的变量(tc_mode)中的各个位代表某个功能是否开启
 * ———————————————————————————————————————————————————————————————————————
 * |      bit7      |       bit6      |       bit5      |       bit4     |
 * |----------------|-----------------|----------------------------------|
 * |     ONLYRET    |      NMQUEUE    |              Reserved            |
 * ———————————————————————————————————————————————————————————————————————
 * |      bit3      |       bit2      |       bit1      |       bit0     |
 * |----------------------------------|-----------------|----------------|
 * |            Reserved              |       DTAG      |       SLIDE    |
 * ———————————————————————————————————————————————————————————————————————
 * Reset value: 0x0000 0000 => 只有单击
 * 
 * ONLYRET: 0:用户在使用接口获取状态时不管状态是过程态还是结果态都获取
 *          1:用户只取结果态，即从队列中获取状态时只获取结果态，忽略掉过程态
 * NMQUEUE:(no maintance queue)
 *          0:系统主动维护状态机队列，将过期的状态出队，保证用户获取的状态是较新的
 *          1:系统不主动维护状态机队列
 * bits [2:5]: 保留
 * DTAG:    0:不判断拖动
 *          1：判断拖动
 * 
 * SLIDE:   0:不判断滑屏
 *          1:判断滑屏
 */
#define TC_GETMODE      1       // 获取当前模式
#define TC_SETMODE      2       // 设置当前模式

#define TC_MODE_ONLYRET (1<<7)
#define TC_MODE_NMQUEUE (1<<6)
#define TC_MODE_DTAG    (1<<1)
#define TC_MODE_SLIDE   (1<<0)
/** 
 *  @}
 */

/** @defgroup 提供给用户使用的接口
 *  @{
 */
pthread_t InitTouch_pthread(void);
bool get_attr_touch(TouchState_t *tc);
bool touch_mode(int32_t cmd, int8_t *mode);
/** 
 *  @}
 */

void *Touch_stateMachine(void *arg);

#endif /* _TOUCH_STATE_H */

/*------------------------------ end of file --------------------------------*/

